package org.dawning.shop.order.command.config;

import com.mongodb.MongoClient;
import org.axonframework.commandhandling.model.Repository;
import org.axonframework.eventhandling.saga.repository.SagaStore;
import org.axonframework.eventsourcing.*;
import org.axonframework.eventsourcing.eventstore.EventStorageEngine;
import org.axonframework.eventsourcing.eventstore.EventStore;
import org.axonframework.mongo.DefaultMongoTemplate;
import org.axonframework.mongo.MongoTemplate;
import org.axonframework.mongo.eventhandling.saga.repository.MongoSagaStore;
import org.axonframework.mongo.eventsourcing.eventstore.MongoEventStorageEngine;
import org.axonframework.serialization.json.JacksonSerializer;
import org.dawning.shop.order.command.aggregate.OrderAggregate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by miou on 2017/5/19 0019.
 */
@Configuration
public class AxonConfiguration {

    @Autowired
    private MongoClient mongo;


    @Bean(name = "axonMongoTemplate")
    MongoTemplate axonMongoTemplate() {
        return new DefaultMongoTemplate(mongo,"scene-shop");
    }

    @Autowired
    @Qualifier("axonMongoTemplate")
    private MongoTemplate mongoTemplate;

    @Bean
    EventStorageEngine eventStorageEngine() {

        return new MongoEventStorageEngine(mongoTemplate);
    }

    @Bean
    public GenericAggregateFactory<OrderAggregate> genericAggregateFactory(){
        return new GenericAggregateFactory<>(OrderAggregate.class);
    }

    @Bean
    public Snapshotter snapshotter(EventStore eventStore){
        return new AggregateSnapshotter(eventStore,genericAggregateFactory());
    }

    @Bean
    public SnapshotTriggerDefinition snapshotTriggerDefinition(EventStore eventStore){
        return new EventCountSnapshotTriggerDefinition(snapshotter(eventStore),100);
    }

    @Bean
    public SagaStore sagaStore(){
        MongoTemplate mongoTemplate =
                new DefaultMongoTemplate(mongo, "scene-shop");
        return new MongoSagaStore(mongoTemplate, new JacksonSerializer());
    }


    //仓储
    @Bean
    public Repository<OrderAggregate> orderAggregateRepository(EventStore eventStore){
        return new EventSourcingRepository<>(OrderAggregate.class, eventStore, snapshotTriggerDefinition(eventStore));
    }

}
